package controller;

import static util.Strings.STR_DICTIONARY;
import static util.Strings.STR_ERROR_OCCURED;
import static util.Strings.STR_NO_TILE;
import static util.Strings.STR_WORD_IN_DICTIONARY;
import static util.Strings.STR_WORD_NOT_IN_DICTIONARY;

import java.util.HashMap;
import java.util.List;

import model.Letter;
import model.Tile;
import util.Coordinate;
import view.swing.ButtonsPanel;
import view.swing.popup.DictionaryLookup;
import view.swing.popup.ErrorMessage;
import view.swing.popup.InfoMessage;
import view.swing.popup.JokerValue;
import view.swing.popup.SwapChooser;

/**
 * Contrôleur représentant les actions du joueur "Passer", "Jouer", "Piocher"
 * 
 * @author Lucile Gramusset et Guillaume Poussel
 * 
 */
public class ActionController extends AbstractController {

    private ButtonsPanel panelButtons;

    /**
     * Construit un contrôleur d'action
     * 
     * @param gameController
     *            Contrôleur du jeu, parent de celui-ci.
     */
    public ActionController(GameController gameController) {
        super(gameController);
        this.panelButtons = new ButtonsPanel(this);
    }

    /**
     * Le joueur passe son tour
     */
    public void skipTurn() {
        // On enlève toutes les tuiles qui ont été posées et on les repose
        ((GameController) getParentController()).getBoardController()
                .resetAllNonFixedTiles();
        // On déslectionne les tuiles
        ((GameController) getParentController()).getRackController().reset();
        // On passe le tour
        ((GameController) getParentController()).skipTurn();
    }

    /**
     * Le joueur veut échanger des tuiles
     */
    public void swap() {

        // On enlève toutes les tuiles qui ont été posées et on les repose
        ((GameController) getParentController()).getBoardController()
                .resetAllNonFixedTiles();
        // On déslectionne les tuiles
        ((GameController) getParentController()).getRackController().reset();
        // On demande à l'utilisateur les lettres qu'il veut échanger
        SwapChooser sc = new SwapChooser(
                ((GameController) getParentController()).getRackController()
                        .getRack().getTiles());
        List<Tile> choice = sc.getChoice();
        if (choice == null || choice.isEmpty()) {
            return;
        }

        //try {
            // On les échange et on passe son tour sans que le changement compte
            // pour un "passe"
            ((GameController) getParentController()).swap(choice);
            ((GameController) getParentController()).skipTurn(false);
            /*
        } catch (EmptyBagException e) {
            ErrorMessage im = new ErrorMessage("Sac", e.getLocalizedMessage());
            im.show();
            return;
        } catch (ForbiddenActionException e) {
            ErrorMessage im = new ErrorMessage(e.getLocalizedMessage());
            im.show();
            return;
        }
        */
    }

    /**
     * Le joueur pose des tuiles et donc joue
     */
    public void playTurn() {
        // On déslectionne les tuiles
        ((GameController) getParentController()).getRackController().reset();
        HashMap<Coordinate, Tile> tiles = ((GameController) getParentController())
                .getBoardController().getNewTiles();
        if (tiles.isEmpty()) {
            ErrorMessage em = new ErrorMessage(STR_ERROR_OCCURED, STR_NO_TILE);
            em.show();
        } else {
            for (Coordinate coord : tiles.keySet()) {
                if (tiles.get(coord).getLetter() == Letter.BLANK) {
                    JokerValue jv = new JokerValue(coord);
                    Letter newLetter = jv.askValue();

                    if (newLetter == null)
                        return;
                    tiles.get(coord).setLetter(newLetter);

                }
            }
            ((GameController) getParentController()).playTurn(tiles);
        }
    }

    /**
     * Recherche dans le dictionnaire
     */
    public void dictionaryLookup() {
        String word = DictionaryLookup.askWord();
        if (word != null && !word.trim().isEmpty()) {
            if (((GameController) getParentController()).checkWord(word)) {
                InfoMessage im = new InfoMessage(STR_DICTIONARY, String.format(
                        STR_WORD_IN_DICTIONARY, word));
                im.show();
            } else {
                ErrorMessage im = new ErrorMessage(STR_DICTIONARY, String
                        .format(STR_WORD_NOT_IN_DICTIONARY, word));
                im.show();
            }
        }
    }

    /**
     * Termine le jeu
     */
    public void endGame() {
        ((GameController) getParentController()).endGame();
    }
    public ButtonsPanel getView() {
        return panelButtons;
    }
}
